作者認為函式是動詞,類別是名詞。程式設計師在撰寫程式時,就像在說故事,需要整潔地結合,並形成精確又清楚的語言。以下列舉撰寫函式時,建議遵守的準則。
(一) 簡短
(二) 只做一件式
public static int[] generatePrimes(int maxValue)
{
if (maxValue >= 2)
{
//declarations
...
//initialize array to true
...
//sieve
...
}
}
(三) 每個函式只有一層抽象概念
由上而下閱讀程式碼: 降層準則,就像閱讀由上而下的敘事,範例如下:
private void includeSetupAndTeardownPages() throws Exception{
includeSetupPages();
includePageContent();
includeTeardownPages();
updatePageContent();
}
private void includeSetupPages() throws Exception{
if (isSuite)
includeSuiteSetupPage();
includeSetupPage();
}
private void includeSuiteSetupPage() throws Exception{
include(SuiteResponder.SUITE_SETUP_NAME, "-setup");
}
private void includeSetupPage() throws Exception{
include(""SetUp, "-setup");
}
(四) Switch敘述
(五) 函式的參數
(六)要無副作用
(七)指令和查詢要分離
(八) 用例外處理取代回傳錯誤碼
(九)不要重複自己
(十) 結構化程式設計
原本: (Listing 3-1)
public static String testableHtml( //自我重複:每次都setup,suitesetup...
PageData pageData
boolean includeSuiteSetup
) throws Exception {
WikiPage wikiPage = pageData.getWikiPage();
StringBuffer buffer = new StringBuffer();
if (pageData.hasAttribute("Test")){ //巢狀結構,縮排超過兩層
if (includeSuiteSetup){
WikiPage suiteSetup=
pageCrawlerImpl.getInheritedPage(
SuiteResponder.SUITE_SETUP_NAME, wikiPage
);
if (suiteSetup != null){
WikiPagePath pagePath =
suiteSetup.getPageCrawler().getFullPath(suiteSetup);
String pagePath = PathParser.render(pagePath); //不同層次同時存在:中層次
buffer.append("!include -setup .") //不同層次同時存在:低層次
.append(pagePathName)
.append("\n");
}
}
WikiPage suiteSetup=......
}
}
經過整章節一步步重構後: (Listing 3-7)
package fitness.html;
import fitness.responder.run.SuiteResponder;
import fitness.wiki.*;
public class SetupTeardownIncluder{
private PageData pageData;
private boolean isSuite;
private WikiPage testPage;
private StringBuffer newPageContent;
private PageCrawler pageCrawler;
public static String render(PageData pageData) throws Exception {
return render(pageData, false);
}
public static String render(PageData pageData, boolean isSuite) throws Exception{
return new SetupTeardownIncluder(pageData).render(isSuite);
}
private SetupTeardownIncluder(PageData pageData){
this.pageData = pageData;
testPage = pageData.getWikiPage();
pageCrawler = testPage.getPageCrawler();
newPageContent = new StringBuffer();
}
private String render(boolean isSuite) throws Exception{
this.isSuite = isSuite;
if (isTestPage())
includeSetupAndTeardownPages(); //由上而下
return pageData.getHtml();
}
private boolean isTestPage() throws Exception{
return pageData.hasAttribute("Test");
}
private void includeSetupAndTeardownPages() throws Exception{ //由上而下
includeSetupPages();
includePageContent();
includeTeardownPages();
updatePageContent();
}
....
}
在了解基本定義後,下一章要談的是註解。